﻿using System.Web;
using System.Web.Mvc;
using Project.MVC.PhanQuyen.Model;

namespace Project.MVC.PhanQuyen.Services
{
    public class WSAuthorizeAttribute : AuthorizeAttribute
    {
        public VuViecEnum Tasks { get; set; } //vụ việc

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            try
            {
                //return base.AuthorizeCore(httpContext);
                if (httpContext == null)
                    return false;
                
                //LẤY DANH SÁCH NGƯỜI SỬ DỤNG
                var users = Users.Split(',');
                
                //LẤY DANH SÁCH CÁC QUYỀN
                var roles = Roles.Split(',');

                if (!httpContext.User.Identity.IsAuthenticated)
                    return false;

                var principal = (WSUserPrincipal)HttpContext.Current.Cache.Get(httpContext.User.Identity.Name);
                if (principal == null)
                    return false;

                principal.Tasks = 0x0;

                if (Roles != "" && roles != null && roles.Length > 0)
                {
                    var userName = httpContext.User.Identity.Name;
                    var services = new PQNguoiDungServices();
                    byte vuViecs = 0;
                    
                    foreach (var role in roles)
                    {
                        var vuViecList = services.GetTasks(userName, role.Trim());

                        if (vuViecList != null && vuViecList.Length > 0)
                        {
                            foreach (var vuViec in vuViecList)
                            {
                                vuViecs |= vuViec;
                            }
                        }
                    }

                    principal.Tasks = (VuViecEnum)vuViecs;

                    // KIỂM TRA NGƯỜI DÙNG CÓ QUYỀN TRUY CẬP HAY KHÔNG 
                    // 
                    if (Tasks > 0x0)
                        return (principal.Tasks & Tasks) > 0x0;
                    else
                        return principal.Tasks > 0x0;
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
            if (filterContext.Result is HttpUnauthorizedResult
                && filterContext.HttpContext.Request.IsAjaxRequest())
            {
                // TODO: fix the URL building: 
                // 1- Use some class to build URLs just in case LoginUrl actually has some query already. 
                HttpRequestBase request = filterContext.HttpContext.Request;
                string returnUrl = request.Path;
                bool queryStringPresent = request.QueryString.Count > 0;
                if (queryStringPresent || request.Form.Count > 0)
                    returnUrl += '?' + request.QueryString.ToString();
                if (queryStringPresent)
                    returnUrl += '&';
                returnUrl += request.Form;
                string url = System.Web.Security.FormsAuthentication.LoginUrl +
                             "?X-Requested-With=XMLHttpRequest&ReturnUrl=" +
                             HttpUtility.UrlEncode(returnUrl);
                filterContext.Result = new RedirectResult(url);
            }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated 
                //&& !filterContext.HttpContext.User.IsInRole(Roles)
                )
            {
                var urlHelper = new UrlHelper(filterContext.RequestContext);
                var result = new RedirectResult(urlHelper.Action("RestrictedAccess", "Account", new { area = "" }));
                filterContext.Result = result;
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }
    }
}